<%
' +----------------------------------------------------------------------
' | POPASP [ ASP MVC ]
' +----------------------------------------------------------------------
' | Copyright (c) 2016 http://popasp.com All rights reserved.
' +----------------------------------------------------------------------
' | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
' +----------------------------------------------------------------------
' | Author: popasp <1737025626@qq.com>
' +----------------------------------------------------------------------
Class POPASP_DICTIONARY
	Public sortByNumeric,sortByDate
	
	Private Sub Class_Initialize
		sortByNumeric = True
		sortByDate = True
	End Sub
	
	'为了减轻重量，特将部分代码写到了另外一个文件
	'POPASP_REPLACE_CLASS_CODE_POPASP'
	
	'''''''''''''修改函数
	
	'向Dictionary对象尾部添加一个键值对
	Sub Push(ByRef dict, ByRef key, ByRef val)
		if typename(dict) <> "Dictionary" then set dict = Create()
		if dict.Exists(key) then
			dict.remove(key)
		end if
		if key = "" then	'如果键名为空，则以当前的个数为键名
			dict.add dict.count,val
		else
			dict.add key,val
		end if
	End Sub
	
	'向Dictionary对象头部添加一个键值对，如果dict为 var("key") 类型则不能添加
	Sub Unshift(ByRef dict,ByRef key,ByRef val)
		if typename(dict) <> "Dictionary" then set dict = Create()
		dim temp
		set temp = Create()
		temp.add key,val
		if typename(dict) <> "Dictionary" then set dict = Create()
		set dict = Merge(temp,dict)	
	end sub
	
	'向Dictionary对象的某个键名前面插入一个键值对
	'如果向不存在的键名前面插入键值对，则会追加到对象尾部
	Sub InsertBefore( ByRef dict, ByRef beforeKey, ByRef key,ByRef val)
		if typename(dict) <> "Dictionary" then set dict = Create()
		
		dim temp,i
		if Not dict.Exists( beforeKey ) Then
			Push dict,key,val
			Exit Sub
		end if
		
		if dict.Exists( key ) Then dict.Remove(key)
		
		for each i in dict
			if i = beforeKey then
				Push temp,key,val
			end if
			Push temp,i,dict.item(i)
		next
		set dict = temp
		set temp = nothing
	End Sub
	
	'向Dictionary对象的某个键名后面插入一个键值对
	'如果向不存在的键名前面插入键值对，则会追加到对象尾部
	Sub InsertAfter( ByRef dict, ByRef afterKey, ByRef key,ByRef val)
		if typename(dict) <> "Dictionary" then set dict = Create()
		
		dim temp,i
		if Not dict.Exists( afterKey ) Then
			Push dict,key,val
			Exit Sub
		end if
		
		if dict.Exists( key ) Then dict.Remove(key)
		
		for each i in dict
			Push temp,i,dict.item(i)
			if i = afterKey then
				Push temp,key,val
			end if			
		next
		set dict = temp
		set temp = nothing
	End Sub
	
	'从Dictionary对象中删除最后一个键值对，并以数组形式返回
	Function Pop(ByRef dict)
		dim key,arr,i,cnt
		
		if typename(dict) <> "Dictionary" then Exit Function
		
		cnt = dict.Count
		
		if cnt = 0 then Exit Function
		
		i = 0
		for each key in dict
			i = i + 1
			if i = cnt then
				POP_MVC.Arr.push arr,key
				POP_MVC.Arr.push arr,dict(key)
				dict.remove(key)
			end if
		next
		Pop = arr
	End Function
	
	'从Dictionary对象中删除第一个键值对，并以数组形式返回
	Function Shift(ByRef dict)
		dim key,arr
		for each key in dict
			POP_MVC.Arr.push arr,key
			POP_MVC.Arr.push arr,dict(key)
			dict.remove(key)
			exit for
		next
		shift = arr
	End Function
	
	' 将Dictionary对象两个键名对应的值进行交换
	Sub vswap( ByRef dict,ByVal key1,ByVal key2 )
		dim temp
		
		if Not dict.Exists( key1 ) OR Not dict.Exists( key2 ) Then Exit Sub
		
		if isObject(dict(key1)) then set temp = dict(key1) else temp = dict(key1)
		call Edit( dict,key1,dict(key2) )
		call Edit( dict,key2,temp )
		if isObject(temp) then set temp = nothing
	End sub
	
	' 将Dictionary对象两个键名进行交换
	Sub kswap( ByRef dict,ByVal key1,ByVal key2 )
		dim k1,k2,key
		key = "__POPASP_|/YouShouldNotGuess\|__POPASP_"
		k1 = key1 : k2 = key2
		dict.key(key2) = key : dict.key(key1) = k2 : dict.key(key) = k1
	End sub
	
	' 将Dictionary对象的两个键值对进行交换，相当于两个键值对交换了位置
	Sub kvswap( ByRef dict,ByVal key1,ByVal key2 )
		call kswap( dict,key1,key2 )
		call vswap( dict,key1,key2 )
	End Sub
	
	' 修改一对键值对，如果存在则修改，否则向尾部添加
	Sub Edit(ByRef dict,ByVal key, ByRef val)
		if typename(dict) <> "Dictionary" then set dict = Create()
		if dict.Exists(key) Then			
			if isObject(val) Then	
				set dict(key) = val
			Else 
				dict(key) = val
			End If							
		else
			dict.add key,val			
		end if
	End Sub
	
	
	'''''''''''查找函数
	
	' 判断某个值是否存在于数组中，返回True或者False
	Function Exists( ByRef dict, ByRef val )
		Exists = (Not isEmpty( Search(dict,val) ))
	End Function

	' 在dict中搜索find，如果存在则返回键名，否则返回Empty
	Function Search( ByRef dict, ByRef val )
		dim key
		for each key in dict
			if POP_MVC.isScalar( dict(key) ) AND dict(key) = val Then
				Search = key
				Exit Function
			End If
		next
	End Function	
	
	'''''''''''数组函数	
	
	' 将键名联接起来，如果只提供一个参数，则默认分隔符为空字符""
	' 如果参数为数组，则第一个参数为Dictionary对象，第二个参数为delimiter
	Function KeyJoin( ByRef args )
		dim delimiter,dict
		delimiter = ""
		if isArray(args) then
			if ubound( args ) > 0  then
				delimiter = CStr(args(1))
			end if
			if isObject( args(0) ) then
				set dict = args(0)
			else 
				dict = args(0)
			end if
		else
			set dict = args
		end if
		
		KeyJoin = ""
		if Typename( dict ) = "Dictionary" then
			KeyJoin = Join( dict.keys , delimiter )
		end if
	end function
	
	' 创建一个空对象
	Function Create()
		set Create = D_
	End Function	
	
	' 克隆一个对象
	Function Clone( ByRef Dict )
		Dim newDict,key
		Set newDict = Create()
		
		For Each key in Dict.Keys
			if isObject ( Dict(key) ) Then
				newDict.Add key, Clone(Dict(key))
			Else 
				newDict.Add key, Dict(key)
			End If	
		Next
		newDict.CompareMode = Dict.CompareMode

		Set Clone = newDict
		set newDict = nothing
	End Function 
	
	' 将值连接起来，如果只提供一个参数，则默认分隔符为空字符""
	' 如果参数为数组，则第一个参数为Dictionary对象，第二个参数为delimiter
	Function ItemJoin( ByRef args )
		dim delimiter,dict
		delimiter = ""
		if isArray(args) then
			if ubound( args ) > 0  then
				delimiter = CStr(args(1))
			end if
			if isObject( args(0) ) then
				set dict = args(0)
			else 
				dict = args(0)
			end if
		else
			set dict = args
		end if
		
		ItemJoin = ""
		if Typename( dict ) = "Dictionary" then
			ItemJoin = Join( dict.items , delimiter )
		end if
	end function
	
	' 合并两个对象
	' 类似于PHP中的 array_merge，如果两个对象中同时存在某键，后者覆盖前者
	Function Merge( ByRef dict1,ByRef dict2 )
		dim key,dict		
		set dict = Clone(dict1)
		For Each key in dict2
			if IsNumeric( key ) then
				Push dict,"",dict2(key)
			else
				Edit dict,key,dict2(key)
			end if
		Next
		set Merge = dict
		set dict = nothing
	End Function
End Class
%>